/*
 * @作者: 沙昊
 * @邮箱: shahao@zju.edu.cn
 * @功能: 
 * @包含算法: 
 * Copyright (c) 2023 by 沙昊, All Rights Reserved. 
 */


class Solution2{
private:
    vector<int> dir{-1,0,1,0,-1};
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix){
        if(matrix.empty())
            return {};
        int n=matrix.size(),m=matrix[0].size();
        vector<vector<int>> dis(n,vector<int>(m,INT_MAX-1));
        queue<pair<int,int>> q;
        for(auto i=0;i<n;i++){
            for(auto j=0;j<m;j++){
                if(src[i][j]==0){
                    q.push({i,j});
                    dis[i][j]=0;
                }
            }
        }
 
        while(!board.empty()){
            auto temp=board.front();
            board.pop();
            for(auto i=0;i<4;i++){
                int x=temp.first+dir[i],y=temp.second+dir[i+1];
                if(x>=0&&x<n&&y>=0&&y<m&&ans[x][y]>ans[temp.first][temp.second]+1){
                    ans[x][y]=ans[temp.first][temp.second]+1;
                    board.push({x,y});/*该点为非零点,入队*/
                }
            }
        }
        return ans;
    }

}


class Solution {
private:
    static constexpr int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        int m = matrix.size(), n = matrix[0].size();
        vector<vector<int>> dist(m, vector<int>(n));
        vector<vector<int>> seen(m, vector<int>(n));
        queue<pair<int, int>> q;
        // 将所有的 0 添加进初始队列中
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    q.emplace(i, j);
                    seen[i][j] = 1;
                }
            }
        }

        // 广度优先搜索
        while (!q.empty()) {
            auto [i, j] = q.front();
            q.pop();
            for (int d = 0; d < 4; ++d) {
                int ni = i + dirs[d][0];
                int nj = j + dirs[d][1];
                if (ni >= 0 && ni < m && nj >= 0 && nj < n && !seen[ni][nj]) {
                    dist[ni][nj] = dist[i][j] + 1;
                    q.emplace(ni, nj);
                    seen[ni][nj] = 1;
                }
            }
        }

        return dist;
    }
};



//爬山，输入：n,m，分别表示一共爬了几天，m表示现存的天数
//输入m组数，[i,j]表示现存的第i天到达的高度j
//输出：若现存记录是有效的，则返回可能到达的最高的高度；若记录是无效的，则返回字符串"IMPOSSIBLE"
//用map<int,int> 记录现存第i天的高度j，用vector记录现存的天数
 
#include <iostream>
#include <vector>
#include <map>
using namespace std;
 
int main()
{

  char a[] =  {'abcd','abcd','abcd'};
  char b[5] =  {'abcd'};
  printf("%d,%d", sizeof(a), sizeof(b));
  
  int n,m;
  backFlag://快速返回的-goto
  while(cin>>n>>m)
  {
    map<int,int> vi;//现存天数-高度
	vector<int> v;//现存天数
	vi.clear();
	v.clear();
	
	int d,h;
	for(int i=0;i<m;i++)
	{
	  cin>>d>>h;
	  v[i]=d;//用v记录现存的天数
	  vi[d]=h;//用vi记录某天的高度
	}
	//将输入的天数进行排序
	sort(v.begin(),v.end());
	//首先处理第一个数据到第一天的最大值？？
	int Max=vi[v[0]]+v[0]-1;
	for(int i=1;i<v.size();i++)
	{
	  if(abs(vi[v[i]]-vi[v[i-1]])>v[i]-v[i-1])
	  {
	    cout<<"IMPOSSIBLE";
		goto backFlag;
	  }
	  else
	  {
	    int tem=(v[i]-v[i-1])/2+(vi[v[i]]+vi[v[i-1]])/2;
		if(tem>Max)  Max=tem;
	  }
	}
	//最后处理以下最后一天的值
	int temp=vi[v[m-1]]+n-v[m-1];
	
	if(temp>Max)
	Max=temp;
	
	//输出最大值
	cout<<Max<<endl;
  }
}